#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define N 256

int main(int argc, char const *argv[])
{
    int udp_fd, tcp_fd;

    // 创建 UDP 套接字
    if ((udp_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    {
        perror("UDP Socket 创建失败");
        return -1;
    }

    // 启用广播
    int on = 1;
    if (setsockopt(udp_fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0)
    {
        perror("广播选项设置失败");
        close(udp_fd);
        close(tcp_fd);
        return -1;
    }

    struct sockaddr_in broad_addr = {
        .sin_family = AF_INET,
        .sin_port = htons(8888),
        .sin_addr.s_addr = inet_addr("255.255.255.255")};

    printf("设备搜索工具\n");
    printf("===========\n");

    while (1)
    {
        printf("\n正在搜索设备...\n");

        // 发送UDP广播搜索请求
        if (sendto(udp_fd, "SEARCH_DEVICE", 13, 0,
                   (struct sockaddr *)&broad_addr, sizeof(broad_addr)) < 0)
        {
            perror("广播发送失败");
            continue;
        }

        // 设置UDP接收超时
        struct timeval tv = {.tv_sec = 2, .tv_usec = 0};
        setsockopt(udp_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

        char buf[N];
        struct sockaddr_in dev_addr;
        socklen_t addrlen = sizeof(dev_addr);
        int device_count = 0;

        // 接收UDP响应
        while (1)
        {
            memset(buf, 0, N);
            int ret = recvfrom(udp_fd, buf, N, 0,
                               (struct sockaddr *)&dev_addr, &addrlen);

            if (ret < 0)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    break; // 超时，没有更多响应
                }
                perror("UDP接收失败");
                continue;
            }

            if (ret > 0)
            {
                device_count++;
                printf("\n设备 #%d:\n", device_count);
                printf("IP地址: %s\n", inet_ntoa(dev_addr.sin_addr));
                printf("端口: %d\n", ntohs(dev_addr.sin_port));

                // 调试输出原始JSON
                printf("收到的JSON: %s\n", buf);

                // 修改JSON解析部分
                char *json = buf;
                char temp[64] = {0};

                // 解析设备类型
                char *type_start = strstr(json, "\"deviceType\":\"");
                if (type_start)
                {
                    type_start += strlen("\"deviceType\":\"");
                    char *type_end = strchr(type_start, '\"');
                    if (type_end)
                    {
                        memset(temp, 0, sizeof(temp));
                        strncpy(temp, type_start, type_end - type_start);
                        printf("设备类型: %s\n", temp);
                    }
                }

                // 解析设备ID
                char *id_start = strstr(json, "\"deviceId\":\"");
                if (id_start)
                {
                    id_start += strlen("\"deviceId\":\"");
                    char *id_end = strchr(id_start, '\"');
                    if (id_end)
                    {
                        memset(temp, 0, sizeof(temp));
                        strncpy(temp, id_start, id_end - id_start);
                        printf("设备ID: %s\n", temp);
                    }
                }

                // 解析版本
                char *version_start = strstr(json, "\"version\":\"");
                if (version_start)
                {
                    version_start += strlen("\"version\":\"");
                    char *version_end = strchr(version_start, '\"');
                    if (version_end)
                    {
                        memset(temp, 0, sizeof(temp));
                        strncpy(temp, version_start, version_end - version_start);
                        printf("版本: %s\n", temp);
                    }
                }
            }
        }

        printf("\n找到 %d 个设备\n", device_count);
        printf("\n按回车键继续搜索，按Ctrl+C退出...\n");
        getchar();
    }

    close(udp_fd);
    return 0;
}
